package org.weso.desempleo.model;

import org.weso.desempleo.services.to.ListGeneroStatsTO;
import org.weso.desempleo.to.GeneroStatsTO;

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;

public class ChargerGeneros extends Charger<ListGeneroStatsTO, GeneroStatsTO>{

	public ChargerGeneros() {
		if(months[0][0] == null)
			initializeMonths();
	}
	
	@Override
	public ListGeneroStatsTO obtain(String lang, String anyo, String month,
			String selector, String langAnt) {
		if(langAnt != null && !langAnt.equals("null") && !langAnt.equals(lang)) {
			selector = getNewSexo(selector, lang, langAnt);
			month = getNewMonth(month, lang, langAnt);
		}
    	String query = prepareSparqlQuery(anyo, selector, month, lang);
    	QueryExecution qExec = initializeQuery("http://156.35.31.156/sparql", query);
    	ListGeneroStatsTO generos = (ListGeneroStatsTO)processResult(qExec.execSelect());
    	return generos;
	}
	
	/**
	 * This method prepare a SPARQL query to obtain the value of a variable
	 * when the user change the language of exhibit page.
	 * @param month The value of month that the user has selected in the form.
	 * @param newLang The new language that the user has selected in the 
	 * exhibit page.
	 * @param oldLang The old language of exhibit page.
	 * @return The SPARQL query.
	 */
	private String prepareLanguageQuery(String sexo, String newLang,
			String oldLang) {
		String query = "PREFIX o: <http://purl.org/observatory/observatory.owl#>\n" + 
				"SELECT DISTINCT ?oldSexo ?newSexo FROM <http://purl.org/weso/testObservatory/observatoryByGenres/>" + 
				"WHERE {?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>" +
				"<http://purl.org/linked-data/cube#Observation>; o:refGenres ?oldSexo;" + 
				"o:refGenres ?newSexo \n FILTER (langMatches(lang(?oldSexo), \"" + oldLang + "\") && str(?oldSexo) =\"" + sexo + "\")" + 
				"FILTER (langMatches(lang(?newSexo), \"" + newLang + "\"))}";
		return query;
	}
	
	private String getNewSexo(String genero, String newLang, String oldLang) {
    	if(genero.equals("Todos") || genero.equals("All"))
			return genero;
		else {
			String query = prepareLanguageQuery(genero, newLang, oldLang);
			QueryExecution qExec = initializeQuery("http://156.35.31.156/sparql", query);
			ResultSet result = qExec.execSelect();
			if(result.hasNext()) {
				QuerySolution solution = result.next();
				String sol = solution.get("newSexo").toString(); 
				return sol.substring(0, sol.indexOf('@'));
			}
			return genero;
		}
    }

	@Override
	public GeneroStatsTO extractData(QuerySolution sol, int observaciones) {
		String label = "o" + String.valueOf(observaciones);
    	String aux = sol.get("month").toString();
    	String m = aux.substring(0, aux.indexOf('@'));
		String month = extractMonth(m);
    	int year = Integer.parseInt(sol.get("year").toString());
    	String sexo = sol.get("sexo").toString();
    	String period = String.valueOf(year) + "-" + month;
    	String dataset = "Paro por sexos en el principado de Asturias desde el año 2005";
    	int unemployment = Integer.parseInt(sol.get("value").toString());
    	GeneroStatsTO genero = new GeneroStatsTO(sexo, label, dataset, year, 
    			unemployment, period, month);
    	return genero;
	}

	@Override
	public ListGeneroStatsTO processResult(ResultSet result) {
		ListGeneroStatsTO generos = new ListGeneroStatsTO();
    	int observaciones = 1;
		while(result.hasNext()) {
			GeneroStatsTO genero = (GeneroStatsTO)extractData(result.next(), 
					observaciones);
			generos.add(genero);
			observaciones++;
		}
    	return generos;
	}

	@Override
	public String prepareSparqlQuery(String anyo, String selector,
			String month, String lang) {
		String query="PREFIX o: <http://purl.org/observatory/observatory.owl#>\n"+
    			"SELECT ?year ?month ?sexo ?value\n FROM " + 
    			"<http://purl.org/weso/testObservatory/observatoryByGenres/> \n WHERE{ ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> " +
    						"<http://purl.org/linked-data/cube#Observation>; o:refYear ?year; o:refMonth ?month; o:unemployment ?value; o:refGenres ?sexo"; 
    	query += parseYear(anyo);
		query += " FILTER (langMatches(lang(?month), \"" + lang +"\")" + parseMonth(month) + ")\n";
		query += " FILTER (langMatches(lang(?sexo), '" + lang +"')" + parseGenres(selector) + ")";
		return query+"}";
	}
	
	private String parseGenres(String genero) {
    	if(genero.equals("Ambos") || genero.equals("Both"))
			return "";
		return "&& str(?sexo)=\"" + genero + "\"";
    }

}
